using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Xml.Serialization;
using Caliburn.Micro;

namespace MediaOwl.Common.IsolatedStorage
{
    public class DeserializeFromIsolatedStorage<T> : IResult
        where T: class, new()
    {
        private readonly string fileName;
        private readonly Action<T> onSuccess;
        private readonly Action<Exception> onFail;

        public DeserializeFromIsolatedStorage(string fileName, Action<T> onSuccess, Action<Exception> onFail = null)
        {
            this.fileName = fileName;
            this.onSuccess = onSuccess;
            this.onFail = onFail;
        }

        public T DeserializedValue { get; private set; }

        public void Execute(ActionExecutionContext context)
        {
            var serializer = new XmlSerializer(typeof(T));
            try
            {
                using (var store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (store.FileExists(fileName))
                    {
                        using (var isoStream = new IsolatedStorageFileStream(fileName, FileMode.Open, FileAccess.Read, store))
                        {
                            DeserializedValue = serializer.Deserialize(isoStream) as T;
                        }
                    }
                }

                if (DeserializedValue != null)
                {
                    if (onSuccess != null)
                        Caliburn.Micro.Execute.OnUIThread(() => onSuccess(DeserializedValue));
                }
                Completed(this, new ResultCompletionEventArgs());
            }
            catch (Exception err)
            {
                if (onFail != null)
                    Caliburn.Micro.Execute.OnUIThread(() => onFail(err));
                Completed(this, new ResultCompletionEventArgs { Error = err });
            }
        }

        public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };
    }
}